

package AddressBook.View;

import AddressBook.Controller.SwingController;
import AddressBook.Model.Contact;
import AddressBook.Model.GroupManager;
import AddressBook.Model.Group;
import AddressBook.View.Dialog.AddContactDialog;
import AddressBook.View.Dialog.MyFileChooser;
import AddressBook.View.Dialog.MyInputDialog;
import AddressBook.View.UtilityView.JtableModelItem;
import AddressBook.View.UtilityView.JtableRender;
//import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * The Class MainView provides functions to display contacts, contact family...
 */
public class MainView extends JFrame implements ViewInterface {
    /**
     * This field allows to define the initial size of the window
     */
    private static final Dimension dimMainView = new Dimension(1000, 500);
    /**
     * This field keeps a reference of the mainPanel
     */
    private JPanel mainPanel;
    /**
     * This field keeps a reference of the menubar
     */
    private MyMenuBar menuBar;
    /**
     * This field keeps a reference of the scrollpane
     */
    private JScrollPane myScrollPane;
    /**
     * This field keeps a reference of the combobox
     */
    private JComboBox myComboBox;

    /**
     * This field keeps a reference of the model
     */
    private GroupManager model;
    /**
     * This field keeps a reference of the file chooser dialog
     */
    private MyFileChooser myFileChooser;

    /**
     * This field keeps a reference of the search panel
     */
    private JPanel searchPanel;

    /**
     * This field keeps a reference of the addContactDialog
     */
    private AddContactDialog addContactDialog;

    /**
     * This field keeps a reference of the removeItemDialog
     */
    private MyInputDialog removeItemDialog;


    private SwingController controller;

    /**
     * This constructor allows to initialize the main view with the specified model
     *
     * @param model The desired model
     */
    public MainView(GroupManager model) {
        super("Contact List Manager");
        this.model = model;
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        initGui();
        setVisible(true);

    }

    /**
     * This method allows to enable the search bar
     *
     * @param visibility The wished visibility
     */
    public void setEnabledSearchBar(boolean visibility) {
        myComboBox.setEnabled(visibility);
    }

    /**
     * This function allows to create and initialize the gui
     */
    public void initGui() {
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setMinimumSize(dimMainView);
        setLocationRelativeTo(null);

        Border panelBorder = BorderFactory.createEmptyBorder(10, 10, 10, 10);

        mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(panelBorder);

        menuBar = new MyMenuBar();
        setJMenuBar(menuBar);

        Border loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);

        TitledBorder textFieldTitle = BorderFactory.createTitledBorder(
                loweredetched, "Search");

        searchPanel = new JPanel();
        searchPanel.setBorder(textFieldTitle);
        myComboBox = new JComboBox();
        myComboBox.setMaximumRowCount(10);
        searchPanel.add(myComboBox);
        searchPanel.setVisible(false);

        mainPanel.add(searchPanel, BorderLayout.PAGE_START);
        myFileChooser = new MyFileChooser();
        addContactDialog = new AddContactDialog(this);
        removeItemDialog = new MyInputDialog(this);

        add(mainPanel);

    }

    /**
     * This method returns a reference of the menuBar
     *
     * @return A reference to the menuBar
     */
    public MyMenuBar getMyMenuBar() {
        return menuBar;
    }

    /**
     * This method allows to display a specified contact
     *
     * @param contact The desired contact
     */
    @Override
    public void displaySpecifiedItem(Contact contact) {
        createScrollTableItem().addItem(contact);

        pack();
    }

    /**
     * This method allows to display all the contacts
     */
    @Override
    public void displayAllContacts() {
        JtableModelItem jtableModelItem = createScrollTableItem();
        for (Group p : model.getGroupArray())
            for (Contact contact : p.getItemArray()) {
                jtableModelItem.addItem(contact);
            }

        pack();
    }

    /**
     * This method allows to display a specified family
     *
     * @param group The desired family
     */
    @Override
    public void displaySpecifiedFamily(Group group) {
        JtableModelItem jtableModelItem = createScrollTableItem();
        for (Contact contact : group.getItemArray()) {
            jtableModelItem.addItem(contact);
        }

        pack();
    }

    /**
     * This method allows to attach data to the search bar
     */
    public void initializeDataSearchBar() {
        myComboBox.removeAllItems();
        myComboBox.addItem("-- ALL --");

        for (Group p : model.getGroupArray()) myComboBox.addItem(p);
        //
        // AutoCompleteDecorator.decorate(myComboBox);

        searchPanel.setVisible(true);
        menuBar.updateVisibilityMenuBar();
    }

    /**
     * This method allows to create a scroll table
     */
    private JtableModelItem createScrollTableItem() {
        if (myScrollPane != null) mainPanel.remove(myScrollPane);
        JTable myTable = new JTable();

        JtableModelItem myJtableModel = new JtableModelItem();
        myJtableModel.setGroupManager(model);
        myJtableModel.setController(controller);

        TableRowSorter<JtableModelItem> sorter = new TableRowSorter<JtableModelItem>(myJtableModel);
        myTable.setModel(myJtableModel);

        for (int i = 0; i < myJtableModel.getColumnCount(); ++i)
            myTable.getColumn(myJtableModel.getColumnName(i)).setCellRenderer(new JtableRender());
        myTable.setRowSorter(sorter);
        myTable.getColumnModel().getColumn(3).setPreferredWidth(200);
        myTable.getColumnModel().getColumn(4).setPreferredWidth(200);
        myTable.getColumnModel().getColumn(7).setPreferredWidth(200);
        myTable.getColumnModel().getColumn(8).setPreferredWidth(200);

        myTable.setGridColor(Color.BLACK);
        myTable.setShowGrid(true);

        myScrollPane = new JScrollPane(myTable);
        mainPanel.add(myScrollPane);

        pack();

        return myJtableModel;

    }


    /**
     * This method allows to attach an action listener to the combobox
     *
     * @param l The desired actionListener
     * @throws NullPointerException If the component is uninstantiated
     */
    public void addActionListenerMyComboBox(ActionListener l) throws NullPointerException {
        if (myComboBox != null)
            myComboBox.addActionListener(l);
        else throw new NullPointerException("Combobox is uninstantiated");
    }

    /**
     * This method allows to display the file chooser
     */
    public void displayFileLoader() {
        myFileChooser.showOpenDialog(this);
    }

    /**
     * This method allows to attach an action listener to the file chooser
     *
     * @param l The desired actionListener
     * @throws NullPointerException If the component is uninstantiated
     */
    public void addActionlistenerFileChooser(ActionListener l) throws NullPointerException {
        if (myFileChooser != null)
            myFileChooser.addActionListener(l);
        else throw new NullPointerException("File chooser is uninstantiated");
    }

    /**
     * This method allows to show an error dialog with the specified message
     *
     * @param msg The message to display
     */
    public void showErrorDialog(String msg) {
        JOptionPane.showMessageDialog(this, msg,
                getTitle(), JOptionPane.ERROR_MESSAGE);
    }

    /**
     * This method return a reference of the addContactDialog
     *
     * @return A reference of the addContactDialog
     */
    public AddContactDialog getAddContactDialog() {
        return addContactDialog;
    }

    /**
     * This method allows to show up the addDialog
     */
    public void showAddDialog() {
        addContactDialog.setVisible(true);
    }

    /**
     * This method allows to show up the remove contact dialog
     */
    public void showInputDialogRemoveItem() {
        removeItemDialog.setText("Choose an item to remove");
        removeItemDialog.attachItem(model.getContactList().toArray());
        removeItemDialog.setVisible(true);
    }

    /**
     * This method returns a reference of the removeItemDialog
     *
     * @return The reference of the removeItemDialog
     */
    public MyInputDialog getRemoveItemDialog() {
        return removeItemDialog;
    }

    /**
     * This method allow to show up the fileSaver
     */
    public void displayFileSaver() {
        myFileChooser.showSaveDialog(this);
    }

    public void setController(SwingController controller) {
        this.controller = controller;
    }
}
